﻿using System.Collections.Specialized;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Moq;

namespace Mvc4Demo.Tests.Extensions
{
    public static class ControllerExtensions
    {
        public static void SetHttpContext(this Controller controller,
                                          RouteData routeData = null,
                                          NameValueCollection queryString = null,
                                          HttpCookieCollection cookies = null)
        {
            controller.ControllerContext = GetMoqControllerContext(controller, routeData,
                                                                   queryString, cookies);

        }



        public static ControllerContext GetMoqControllerContext(Controller controller,
                                                                RouteData routeData = null,
                                                                NameValueCollection queryString = null,
                                                                HttpCookieCollection cookies = null)
        {
            cookies = cookies ?? new HttpCookieCollection();
            queryString = queryString ?? new NameValueCollection();
            routeData = routeData ?? GetDefaultRouteData();

            var moqHttpContext = new Mock<HttpContextBase>();
            var moqRequest = new Mock<HttpRequestBase>();
            var moqResponse = new Mock<HttpResponseBase>();
            var moqServer = new Mock<HttpServerUtilityBase>();

            moqRequest.SetupGet(x => x.QueryString).Returns(queryString);
            moqRequest.SetupGet(x => x.Cookies).Returns(cookies);
            moqServer.Setup(x => x.MapPath(It.IsAny<string>())).Returns("http://tempuri.com");

            moqHttpContext.Setup(x => x.Request).Returns(moqRequest.Object);
            moqHttpContext.Setup(x => x.Response).Returns(moqResponse.Object);
            moqHttpContext.Setup(x => x.Server).Returns(moqServer.Object);
            moqHttpContext.Setup(x => x.User).Returns(() => new TestPrincipal());

            controller.Url = new UrlHelper(new RequestContext(moqHttpContext.Object, routeData));

            return new ControllerContext(moqHttpContext.Object, routeData, controller);
        }

        private static RouteData GetDefaultRouteData()
        {
            var routeData = new RouteData();
            routeData.Values.Add("action", "Index");
            routeData.Values.Add("controller", "Home");
            return routeData;
        }

        internal class TestPrincipal : IPrincipal
        {
            readonly TestIdentity _identity = new TestIdentity();

            public IIdentity Identity
            {
                get { return _identity; }
            }

            public bool IsInRole(string role)
            {
                return true;
            }
        }

        internal class TestIdentity : IIdentity
        {

            public string AuthenticationType
            {
                get { return string.Empty; }
            }

            public bool IsAuthenticated
            {
                get { return true; }
            }

            public string Name
            {
                get { return "TestUser"; }
            }
        }
    }
}
